package com.wu.family.utils.audio;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Path;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;

public class SoundMgr {
	public final static String SOUND_CACHE_PATH = Environment.getExternalStorageDirectory() + "/family/.sound/";
	private static SoundMgr instance = null;
	private ExecutorService executorService = Executors.newFixedThreadPool(5);
	public Map<String, WeakReference<String>> soundPathCache = new HashMap<String, WeakReference<String>>();
	
	private SoundMgr() {
		File dir = new File(SOUND_CACHE_PATH);
		if ( !dir.exists()) {
			dir.mkdirs();
		}
	}
	
	public static SoundMgr getInstance() {
		if (instance == null) {
			instance = new SoundMgr();
		}
		return instance;
	}
	
	public void removeSoundCache(String url) {
		if (soundPathCache.containsKey(url)) {
			soundPathCache.remove(url);
		}
		
		File cacheFile = new File( SOUND_CACHE_PATH + formatString(url));
		if ( cacheFile.exists() ) {
			cacheFile.delete();
		}
	}
	
	public void addSoundCache(String url, String path)
	{
		try {
			if(path != null) {
				soundPathCache.put(url, new WeakReference<String>(path));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public String getSoundPath(final String url, SoundCallBack customCallBack)
	{
		final SoundCallBack callBack;
		if (customCallBack != null) {
			callBack = customCallBack;
		}else {
			callBack = defaultCallBack;
		}
		
		final Handler  handler =  new Handler() {
			public void handleMessage(Message msg) {
				if( msg.what == 0 ) {
					callBack.onFoundCachePath(url, (String) msg.obj);
				
				}else if( msg.what == 1 ) {
					if ( msg.obj == null ) {
						netLoadFile(url, this);
					}else{
						callBack.onFoundCachePath(url, (String) msg.obj);
					}
				}
			}; 
		};
		 
		if (soundPathCache.containsKey(url)) {
            WeakReference<String> softReference = soundPathCache.get(url);
            String path = softReference != null ? softReference.get() : null;
            if ( null == path ) {
            	soundPathCache.remove(url);
            	getSoundPath(url,callBack);
			}else {
				callBack.onFoundCachePath(url, path);
	            return path;
			}
		}else {
			findLocalFile(url, handler); 
		}
		return null;
	}
	
	public void findLocalFile(final String url,final Handler handler) {
		executorService.submit(new Runnable() {
			@Override
			public void run() {
				String path = null;
				try {
					File cacheFile = new File( SOUND_CACHE_PATH + formatString( url ) );
					if ( cacheFile.exists() ) {
						path = cacheFile.getAbsolutePath();
					}
					if(path != null){
						soundPathCache.put(url, new WeakReference<String>(path));
					}
					handler.sendMessage(handler.obtainMessage(1, path));
					
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
				}
			}
		});
	}
	public void netLoadFile(final String url,final Handler handler)
	{
		executorService.submit(new Runnable() {
			
			@Override
			public void run() {
				File file = null;
				FileOutputStream outputStream = null;
				BufferedInputStream bufInputStream = null;
				try {
					HttpURLConnection conn = (HttpURLConnection)new URL(url).openConnection();
					conn.setConnectTimeout(5 * 1000); 
					conn.setRequestMethod("GET");
					if(conn.getResponseCode()==200){
						file = new File(SOUND_CACHE_PATH + formatString( url ));
						if (file.exists()) {
							file.delete();
						}
						file.createNewFile();
						
						bufInputStream = new BufferedInputStream(conn.getInputStream());
						outputStream = new FileOutputStream(file);
						byte[] buffer = new byte[1024];
						int len = 0;
						while( (len = bufInputStream.read(buffer)) !=-1 ){
							outputStream.write(buffer, 0, len);
						}
						
						outputStream.flush();
						
						String path = file.getAbsolutePath();
						soundPathCache.put(url, new WeakReference<String>(path));
						handler.sendMessage(handler.obtainMessage(0, path));
					}
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					try {
						if (outputStream != null) {
							outputStream.flush();
							outputStream.close();
							outputStream = null;
						}
						if (bufInputStream != null) {
							bufInputStream.close();
							bufInputStream = null;
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		});
	}
	
	public SoundCallBack defaultCallBack = new SoundCallBack() {

		@Override
		public void onFoundCachePath(String url, String path) {
			SoundPlayer.getInstance().playMusic(path);
		}
	};
	
	public String formatString( final String from ) {
		//return MD5.MD5Encode(from)+ ((from.lastIndexOf(".")!=-1)?from.substring(from.lastIndexOf(".")):".jpg");
		String formatString = new String(from);
		String[] strs = formatString.split("/");
		formatString = "";
		for( int i=0; i<strs.length; i++ )
		{
			formatString = formatString + strs[i];
		}
		int index = formatString.lastIndexOf("com");
		formatString = formatString.substring(index!=-1?index:0);
		
		return formatString;
	}
	
	public interface SoundCallBack {
		public void onFoundCachePath(String url, String path);
	}
}
